package com.evil.common.application.enums.order;

import cn.hutool.core.collection.ListUtil;
import com.evil.common.application.dto.order.data.ControlDataValueDTO;
import com.evil.common.application.dto.process.node.NodeBaseDTO;
import com.evil.common.core.enums.BaseEnum;
import com.evil.common.family.enums.RCodeEnum;
import com.evil.common.core.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 流程状态
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@AllArgsConstructor
public enum OrderProcessStatusEnum {

    /**
     * 流程状态(0:草稿箱, 1:流程中, 2:已完成)
     */
    DRAFT_BOX(0, -1L, "草稿箱"),
    PROCESSING(1, 0L, "流程中"),
    COMPLETED(2, -2L, "已完成"),
    REFUSE(3, -3L, "已拒绝"),
    ;

    @Getter
    private final int id;
    @Getter
    private final long nodeId;
    @Getter
    private final String name;

    /**
     * 转换流程节点数据
     *
     * @param dataValues  dataValues
     * @param nodeBaseMap nodeBaseMap
     * @return List
     */
    public List<ControlDataValueDTO> nodeNameConvert(List<ControlDataValueDTO> dataValues, Map<Long, NodeBaseDTO> nodeBaseMap) {
        switch (this) {
            case DRAFT_BOX:
                // 草稿箱
                ControlDataValueDTO draftBox = new ControlDataValueDTO(DRAFT_BOX.nodeId, DRAFT_BOX.name);
                draftBox.setValue(DRAFT_BOX.name);
                draftBox.setOtherInfo(new NodeBaseDTO(draftBox.getId(), null, draftBox.getValue()));
                return ListUtil.toList(draftBox);
            case COMPLETED:
                // 已完成
                ControlDataValueDTO completed = new ControlDataValueDTO(COMPLETED.nodeId, COMPLETED.name);
                completed.setValue(COMPLETED.name);
                completed.setOtherInfo(new NodeBaseDTO(completed.getId(), null, completed.getValue()));
                return ListUtil.toList(completed);
            case REFUSE:
                // 已拒绝
                ControlDataValueDTO refuse = new ControlDataValueDTO(REFUSE.nodeId, REFUSE.name);
                refuse.setValue(REFUSE.name);
                refuse.setOtherInfo(new NodeBaseDTO(refuse.getId(), null, refuse.getValue()));
                return ListUtil.toList(refuse);
            default:
                // 流程中
                return dataValues.stream()
                        .peek(value -> {
                            NodeBaseDTO nodeBaseDTO = nodeBaseMap.get(value.getId());
                            value.setValue(null != nodeBaseDTO ? nodeBaseDTO.getNodeName() : null);
                            value.setOtherInfo(nodeBaseDTO);
                        })
                        .collect(Collectors.toList());
        }
    }

    public static Optional<OrderProcessStatusEnum> isExistById(Integer id) {
        if (null == id) {
            return Optional.empty();
        }
        return Arrays.stream(values()).filter(e -> e.id == id).findFirst();
    }

    public static OrderProcessStatusEnum findById(Integer id) {
        return OrderProcessStatusEnum.isExistById(id).orElseThrow(() ->
                new BusinessException(BaseEnum.ERROR_PARAMETER, "订单流程状态参数错误"));
    }

    public static Optional<OrderProcessStatusEnum> isExistByNodeId(Long nodeId) {
        if (null == nodeId) {
            return Optional.empty();
        }
        return Arrays.stream(values()).filter(e -> e.nodeId == nodeId).findFirst();
    }
}
